home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / graphics / flick_1.0 / source / flick.c < prev    next >
C/C++ Source or Header  |  1994-11-17  |  29KB  |  935 lines

  1. /*****************************************************************************
  2.  
  3.         Flick FLI-format Animation Viewer v1.0          19 Dec 1993
  4.         --------------------------------------
  5.  
  6.  
  7. This program plays 320x200x8 FLI-format bitmapped animation files on
  8. any ECS or AGA Amiga running OS2.04 or higher.  FLI-format files are
  9. produced by Autodesk Animator and Autodesk 3D Studio on a PC, as well
  10. as by other programs.
  11.  
  12. The files in this archive may be distributed anywhere provided they are
  13. unmodified and are not sold for profit.
  14.  
  15. Ownership and copyright of all files remains with the author:
  16.  
  17.     Peter McGavin, 86 Totara Crescent, Lower Hutt, New Zealand.
  18.     e-mail: peterm@maths.grace.cri.nz
  19.  
  20. *****************************************************************************/
  21.  
  22. #include "includes.h"
  23.  
  24. long __oslibversion = 37;    /* we require at least OS2.0 */
  25.  
  26. char __stdiowin[] = "CON:20/50/500/130/Flick";
  27. char __stdiov37[] = "/AUTO/CLOSE";
  28.  
  29. void __asm chunky2planar320x200 (register __a0 UBYTE *chunky_data,
  30.                                  register __a1 PLANEPTR raster,
  31.                                  register __a3 UBYTE *buff0,
  32.                                  register __a4 UBYTE *buff1,
  33.                                  register __a5 struct Library *TimerBase,
  34.                                  register __a6 struct GfxBase *GfxBase);
  35.  
  36. void __asm chunky2planar640x480 (register __a0 UBYTE *chunky_data,
  37.                                  register __a1 PLANEPTR raster,
  38.                                  register __a3 UBYTE *buff0,
  39.                                  register __a4 UBYTE *buff1,
  40.                                  register __a5 struct Library *TimerBase,
  41.                                  register __a6 struct GfxBase *GfxBase);
  42.  
  43. #define FLI_256_COLOR  4
  44. #define FLI_DELTA      7
  45. #define FLI_COLOR     11
  46. #define FLI_LC        12
  47. #define FLI_BLACK     13
  48. #define FLI_BRUN      15
  49. #define FLI_COPY      16
  50. #define FLI_MINI      18
  51.  
  52. struct header {
  53.   ULONG size;
  54.   UWORD magic;
  55.   UWORD frames;
  56.   UWORD width;
  57.   UWORD height;
  58.   UWORD depth;
  59.   UWORD flags;
  60.   UWORD speed;
  61.   ULONG next;
  62.   ULONG frit;
  63.   UBYTE expand[102];
  64. };
  65.  
  66. struct frameheader {
  67.   ULONG size;
  68.   UWORD magic;
  69.   UWORD chunks;
  70.   UBYTE expand[8];
  71. };
  72.  
  73. struct chunkheader {
  74.   ULONG size;
  75.   UWORD type;
  76. };
  77.  
  78. typedef enum mode_type {MODE_COLOUR, MODE_EHB, MODE_GREY};
  79.  
  80. #define BITMAP_DEPTH 8
  81.  
  82. PLANEPTR raster[2] = {NULL, NULL};    /* 8 contiguous bitplanes */
  83. struct BitMap screen_bm[2];    /* The displayed bitmap (may be less planes) */
  84. struct BitMap bitmap_bm[2];    /* The full depth-8 bitmap */
  85. struct RastPort rp[2];
  86. UBYTE *buff0 = NULL;        /* CHIP buffer for chunky2planar */
  87. UBYTE *buff1 = NULL;        /* CHIP buffer for chunky2planar */
  88.  
  89. UWORD __chip emptypointer[] = {
  90.     0x0000, 0x0000,        /* reserved, must be NULL */
  91.     0x0000, 0x0000,     /* 1 row of image data */
  92.     0x0000, 0x0000};    /* reserved, must be NULL */
  93.  
  94. struct NewScreen ns = {
  95.         0,0,0,0,0,
  96.         2,1,
  97.         0 /* HIRES | LACE */,
  98.         CUSTOMSCREEN | CUSTOMBITMAP,
  99.         NULL,
  100.         NULL,
  101.         NULL,
  102.         &screen_bm[0]
  103. };
  104.  
  105. struct NewWindow nw = {
  106.         0,0,            /* Starting corner */
  107.         0,0,            /* Width, height */
  108.         2,1,            /* detail, block pens */
  109.         VANILLAKEY,        /* IDCMP flags */
  110.         ACTIVATE|BORDERLESS,    /* Window flags */
  111.         NULL,            /* Pointer to first gadget */
  112.         NULL,            /* Pointer to checkmark */
  113.         NULL,            /* title */
  114.         NULL,            /* screen pointer */
  115.         NULL,            /* bitmap pointer */
  116.         0,0,0,0,        /* window not sized */
  117.         CUSTOMSCREEN        /* type of screen */
  118.         };
  119.  
  120. struct Screen *s = NULL;
  121. struct Window *w = NULL;
  122.  
  123. struct header h;
  124. struct frameheader *fh;
  125. struct chunkheader *ch;
  126.  
  127. struct Library *TimerBase = NULL;
  128. struct timerequest *timerio = NULL;
  129. ULONG timerclosed = TRUE;
  130. struct EClockVal *time0 = NULL;
  131. struct EClockVal *time1 = NULL;
  132. double micros_per_eclock;    /* Length of EClock tick in microseconds */
  133.  
  134. char programname[20];
  135. BPTR olddir = NULL;
  136. struct RDArgs *rdargs = NULL;
  137.  
  138. /****************************************************************************/
  139.  
  140. void swapw (UWORD *w)
  141. /* Swap the bytes around in a word which may be on an odd byte-boundary */
  142. {
  143.   UBYTE t;
  144.  
  145.   t = ((UBYTE *)w)[0];
  146.   ((UBYTE *)w)[0] = ((UBYTE *)w)[1];
  147.   ((UBYTE *)w)[1] = t;
  148. }
  149.  
  150. void swapl (ULONG *l)
  151. /* Swap the bytes around in a longword which may be on an odd byte-boundary */
  152. {
  153.   UBYTE t;
  154.  
  155.   t = ((UBYTE *)l)[0];
  156.   ((UBYTE *)l)[0] = ((UBYTE *)l)[3];
  157.   ((UBYTE *)l)[3] = t;
  158.   t = ((UBYTE *)l)[1];
  159.   ((UBYTE *)l)[1] = ((UBYTE *)l)[2];
  160.   ((UBYTE *)l)[2] = t;
  161. }
  162.  
  163. UWORD extractw (UWORD *w)
  164. /* Get a word which may be on an odd byte-boundary */
  165. {
  166.   UBYTE t[2];
  167.  
  168.   t[0] = ((UBYTE *)w)[0];
  169.   t[1] = ((UBYTE *)w)[1];
  170.   return *(UWORD *)t;
  171. }
  172.  
  173. ULONG extractl (ULONG *l)
  174. /* Get a longword which may be on an odd byte-boundary */
  175. {
  176.   UBYTE t[4];
  177.  
  178.   t[0] = ((UBYTE *)l)[0];
  179.   t[1] = ((UBYTE *)l)[1];
  180.   t[2] = ((UBYTE *)l)[2];
  181.   t[3] = ((UBYTE *)l)[3];
  182.   return *(ULONG *)t;
  183. }
  184.  
  185. /****************************************************************************/
  186.  
  187. void _STDcleanup (void)
  188. /* This get called automatically by SAS/C 6.3 on any sort of exit condition */
  189. {
  190.   int which;
  191.  
  192.   if (w != NULL) {
  193.     CloseWindow (w);
  194.     w = NULL;
  195.   }
  196.   if (s != NULL) {
  197.     CloseScreen (s);
  198.     s = NULL;
  199.   }
  200.   if (buff0 != NULL) {
  201.     FreeMem (buff0, h.width * (ULONG)h.height);
  202.     buff0 = NULL;
  203.   }
  204.   if (buff1 != NULL) {
  205.     FreeMem (buff1, h.width * (ULONG)h.height);
  206.     buff1 = NULL;
  207.   }
  208.   for (which = 0; which < 2; which++) {
  209.     if (raster[which] != NULL) {
  210.       FreeRaster (raster[which], h.width, BITMAP_DEPTH * h.height);
  211.       raster[which] = NULL;
  212.     }
  213.   }
  214.   if (time1 != NULL) {
  215.     FreeMem (time1, sizeof(struct EClockVal));
  216.     time1 = NULL;
  217.   }
  218.   if (time0 != NULL) {
  219.     FreeMem (time0, sizeof(struct EClockVal));
  220.     time0 = NULL;
  221.   }
  222.   if (olddir != NULL) {
  223.     CurrentDir (olddir);
  224.     olddir = NULL;
  225.   }
  226.   if (rdargs != NULL) {
  227.     FreeArgs (rdargs);
  228.     rdargs = NULL;
  229.   }
  230.   if (!timerclosed) {
  231.     CloseDevice ((struct IORequest *)timerio);
  232.     TimerBase = NULL;
  233.   }
  234.   if (timerio != NULL) {
  235.     FreeMem (timerio, sizeof(struct timerequest));
  236.     timerio = NULL;
  237.   }
  238.   /* standard libraries are auto-closed here by SAS/C */
  239. }
  240.  
  241. /****************************************************************************/
  242.  
  243. void die (char *msg, ...)
  244. /* Exit program with message, return code 10 */
  245. {
  246.   va_list arglist;
  247.  
  248.   WBenchToFront ();
  249.   va_start (arglist, msg);
  250.   vfprintf (stderr, msg, arglist);
  251.   va_end (arglist);
  252.   Delay (200);
  253.   exit (10);
  254.   /* SAS/C executes _STDcleanup() automatically on exit */
  255. }
  256.  
  257. /****************************************************************************/
  258.  
  259. void animate_file (char *fname, BOOL ram, enum mode_type mode, BOOL once)
  260. {
  261.   FILE *f;
  262.   ULONG size, y, class, bytesleftinframe, totalframes, restartpos, l;
  263.   UWORD i, frame, chunk, code;
  264.   UWORD packet, packets, n, m, c, x, line, lines, bsize, depth, which;
  265.   UWORD *viewcolourtable, screen_depth;
  266.   struct IntuiMessage *msg;
  267.   UBYTE *filebuf, *buf, *chunkbuf, *p, *p2, *chunky, *restartptr, *xlate;
  268.   UBYTE (*colourtable)[256][3], pattern[2];
  269.   BOOL going, firstloop;
  270.   ULONG fh_size, ch_size;
  271.   UWORD fh_magic, fh_chunks, ch_type;
  272.  
  273.   /* open file and read header struct */
  274.   if ((f = fopen (fname, "rb")) == NULL)
  275.     die ("%s: Can't open %s\n", programname, fname);
  276.   if ((fread (&h, sizeof(struct header), 1, f)) != 1)
  277.     die ("%s: Error reading file\n", programname);
  278.   swapl (&h.size);
  279.   swapw (&h.magic);
  280.   swapw (&h.frames);
  281.   swapw (&h.width);
  282.   swapw (&h.height);
  283.   swapw (&h.depth);
  284.   swapw (&h.flags);
  285.   swapw (&h.speed);
  286.   swapl (&h.next);
  287.   swapl (&h.frit);
  288.   printf ("File = %s\n", fname);
  289.   printf ("%lu bytes, %u frames, %ux%ux%u, speed = %u\n", h.size, h.frames,
  290.           h.width, h.height, h.depth, h.speed);
  291.   if (h.magic != 0xaf11 && h.magic != 0xaf12)
  292.     die ("%s: Unrecognised magic number %04x\n", programname, h.magic);
  293.   if ((h.width != 320 || h.height != 200) && (h.width != 640 || h.height != 480))
  294.     die ("%s: Unsupported dimensions\n", programname);
  295.  
  296.   /* allocate chunky pixels */
  297.   if ((chunky = malloc (h.width * (ULONG)h.height)) == NULL)
  298.     die ("%s: Out of memory\n", programname);
  299.   memset (chunky, 0, h.width * (ULONG)h.height);
  300.  
  301.   /* allocate 2 rasters (for double-buffering) */
  302.   screen_depth = 8;
  303.   for (which = 0; whi